package weeny.recycle;

import java.awt.Event;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.Random;
import java.util.Stack;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * DEAD 
 * 
 * @author weeny
 */
@Deprecated
public class Control {
	
	public static String SLASH = System.getProperty("file.separator");
	private static SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("MM_dd_HH_mm_ss(SSS)");
	private static String FOLDER = null;
	public static String desktopFolder(){
		return System.getProperty("user.home")+SLASH+"Desktop"+SLASH;
	}
	private static String desktopTemporalDirectory(){
		if (System.getProperties().get("os.name").toString().startsWith("Mac")) {
			File file = new File(desktopFolder()+timeString());
			file.mkdir();
			return file.getAbsolutePath()+SLASH;
		}
		else {
			File file = new File("c:"+SLASH+"javaDebug");
			if (!file.exists()) { file.mkdir(); }
			file = new File("c:"+SLASH+"javaDebug"+SLASH+timeString());
			file.mkdir();
			return file.getAbsolutePath()+SLASH; 
		}
	}
	public static String outputFolder(){
		if (FOLDER != null) {
			//if the folder does not exist
			if (!new File(FOLDER).exists()) {
				new File(FOLDER).mkdirs();
			}
			return FOLDER;
		}
		FOLDER = desktopTemporalDirectory();
		return FOLDER;
	}
	public static String resultFolder(){
		if (FOLDER != null) {
			//if the folder does not exist
			if (!new File(FOLDER).exists()) {
				new File(FOLDER).mkdirs();
			}
			return FOLDER;
		}
		FOLDER = desktopTemporalDirectory();
		return FOLDER;
	}
	
	public static class Pair<U,V>{
		private U u;
		private V v;
		public Pair(U u, V v) {
			this.u = u;
			this.v = v;
		}
		public U first(){
			return u;
		}
		public V second(){
			return v;
		}
	}
	
	public static BufferedReader br(String fileName){
		try {
			return new BufferedReader(new FileReader(fileName));
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}
		return null; 
	}
	public static LineIterator lineIterator(File file){
		try {
			return new LineIterator(new BufferedReader(new FileReader(file)));
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}
		return null;
	}
	public static LineIterator lineIterator(String file){
		try {
			return new LineIterator(new BufferedReader(new FileReader(file)));
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}
		return null;
	}
	public static String readAll(String fileName){
		StringBuffer sb= new StringBuffer();
		for(LineIterator it = new LineIterator(fileName); it.hasNext();){
			sb.append(it.next());
			sb.append(it.hasNext()? "\n":"");
		}
		return sb.toString();
	}
	public static class LineIterator implements Iterator<String>{
		private BufferedReader reader = null;
		private String line = null;
		private boolean hasNext = false;
		private int currentLine = -1;
		private void updateLine(){
			try {
				line = reader.readLine();
				if (line == null) {
					reader.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
			hasNext = line != null;
			currentLine += 1;
		}
		public LineIterator(InputStream is){
			InputStreamReader isr = new InputStreamReader(is);
			this.reader = new BufferedReader(isr);
			updateLine();
		}
		public LineIterator(String fileName){
			try {
				FileReader fr = new FileReader(fileName);
				this.reader = new BufferedReader(fr);
				updateLine();
			} catch (FileNotFoundException e) {
				e.printStackTrace();
			}
		}
		public LineIterator(BufferedReader br) {
			this.reader = br;
			updateLine();
		}
		public boolean hasNext() {
			return hasNext;
		}
		public String next() {
			if (hasNext) {
				String result = line;
				updateLine();
				return result;
			}
			else{
				throw new NoSuchElementException("no more lines");
			}
		}
		public void remove() {
			throw new UnsupportedOperationException("cannot remove line from a reader");
		}
		/**
		 * get the line id (from #0) of the line got from last next() call
		 */
		public int lineNumber(){
			return currentLine-1;
		}
	}
	public static String folderFile(String fileName){
		return resultFolder()+fileName;
	}
	public static List<String> subFilesWithExt(String ext, File dir){
		List<String> result = new ArrayList<String>();
		File[] files = dir.listFiles();
		for (File file : files) {
			if (file.isFile() && !file.isHidden() && !file.getName().startsWith(".")) {
				if (file.getAbsolutePath().endsWith(ext))
					result.add(file.getAbsolutePath());
			}	
		}
		return result;
	}
	public static List<String> searchFileMatches(String regex, File ...dirs){
		List<String> names = searchFiles(dirs);
		List<String> result = new ArrayList<String>();
		Pattern p = Pattern.compile(regex);
		for(String name : names){
			Matcher m = p.matcher(new File(name).getName());
			if (m.matches()) {
				result.add(name);
			}
		}
		return result;
	}
	public static List<String> searchFilesWithoutExt(String ext, File ...dirs){
		List<String> names = searchFiles(dirs);
		List<String> result = new ArrayList<String>();
		for(String name : names){
			if (!name.endsWith(ext)) {
				result.add(name);
			}
		}
		return result;
	}
	public static List<String> searchFilesWithExt(String ext, File... dirs){
		List<String> names = searchFiles(dirs);
		List<String> result = new ArrayList<String>();
		for(String name : names){
			if (name.endsWith(ext)) {
				result.add(name);
			}
		}
		return result;
	}
	public static List<String> searchFiles(File... dirs){
		List<String> result = new ArrayList<String>();
		for (File d : dirs){
			searchFiles(d, result);
		}
		return result;
	}
	private static void searchFiles(File dir, List<String> result){
		if (dir.isFile() && !dir.isHidden() && !dir.getName().startsWith(".")) {
			result.add(dir.getAbsolutePath());
		}
		else if(dir.isDirectory()){
			File[] files = dir.listFiles();
			for (File file2 : files) {
				searchFiles(file2, result);
			}
		}
	}
	
	public static String desktopFolder(String dir){
		return System.getProperty("user.home")+SLASH+"Desktop"+SLASH+dir+SLASH;
	}
	public static String projectFolder(){
		return System.getProperty("user.dir")+SLASH;
	}

	public static String projectTemporalDirectory(){
		String resultFolder =  System.getProperty("user.dir")+SLASH+"tempResult";
		if (!new File(resultFolder).exists() || !new File(resultFolder).isDirectory()) {
			new File(resultFolder).mkdirs();
		}
		return resultFolder+SLASH+timeString()+SLASH;
	}
	
	public static String timeString(){
		Date date = new Date(System.currentTimeMillis());
		return DATE_FORMAT.format(date);
	}
	
	public static Stack<Long> LONGSEED = new Stack<Long>();
	static{/* use the seeds sequence to avoid unprediction */
 		LONGSEED.push(11223344L);
		Random rand = new Random(12345679L);
		for(int i = 0; i<128; i++){
			LONGSEED.push(rand.nextLong());
		}
	}
	public static String fill(int i, int length, char c){
		String str = i+"";
		while (str.length()<length) {
			str = c+str;
		}
		return str;
	}
	
	public static int[] shuffle(int[] array, Random rand){
		int[] result = new int[array.length];
		List<Integer> list = new ArrayList<Integer>(array.length+1);
		for(int i = 0; i<array.length; i++){
			list.add(array[i]);
		}
		if (rand == null) {
			Collections.shuffle(list);
		}
		else{
			Collections.shuffle(list, rand);
		}
		for(int i = 0; i<list.size(); i++){
			result[i] = list.get(i);
		}
		return result;
	}
	
	public static boolean isShiftDown(int modifier){
		return (modifier&Event.SHIFT_MASK)!=0;
	}
	public static boolean isAltDown(int modifier){
		return (modifier&Event.ALT_MASK)!=0;
	}

	public static double max(double[] varValues) {
		double max = Double.MIN_VALUE;
		for(int i = 0; i<varValues.length; i++){
			if (varValues[i]>max) {
				max = varValues[i];
			}
		}
		return max;
	}
}
